package signal

import (
	"encoding/json"
	"fmt"
	"github.com/gorilla/websocket"
	"log"
	"net/http"
	"strconv"
	"time"
)

type User struct {
	offer  string
	conn   *websocket.Conn
	answer string
	ice    []string //如果pc1是本地流，pc2是远端流 ice是pc1在setlocatdes后产生的ice
}

type Rooms struct {
	rooms       [][]User
	outsideRoom []User
}

var (
	allRooms Rooms
)

func init() {
	allRooms.rooms = make([][]User, 3)
}

func (r *Rooms) transformOffer(c *websocket.Conn, offer string) {
	var roomdId int
	for index, v := range r.rooms {
		for j, item := range v {
			if item.conn == c {
				roomdId = index
				r.rooms[index][j].offer = offer
			}
		}
	}
	var room = r.rooms[roomdId]
	if len(room) >= 2 {
		//让后来的发offer
		for _, v := range room {
			if v.conn != c {
				var res = map[string]string{"mode": "offer", "offer": offer}
				v.conn.WriteJSON(res)
			}
		}
	}
}
func (r *Rooms) transformAnswer(c *websocket.Conn, answer string) {
	var roomdId int
	for index, v := range r.rooms {
		for j, item := range v {
			if item.conn == c {
				roomdId = index
				r.rooms[index][j].answer = answer
			}
		}
	}
	var room = r.rooms[roomdId]
	for i, v := range room {
		if v.conn != c {
			pipe := room[i].conn
			var res = map[string]string{"mode": "answer", "answer": answer}
			pipe.WriteJSON(res)
		}
	}
}
func (r *Rooms) transformIce(c *websocket.Conn, ice string) {
	var roomdId int
	for index, v := range r.rooms {
		for j, item := range v {
			if item.conn == c {
				roomdId = index
				r.rooms[index][j].ice = append(r.rooms[index][j].ice, ice)
			}
		}
	}
	var room = r.rooms[roomdId]
	for i, v := range room {
		if v.conn != c {
			pipe := room[i].conn
			var res = map[string]string{"mode": "ice", "ice": ice}
			pipe.WriteJSON(res)
		}
	}
}

func (r *Rooms) boardRoomsNum(user *websocket.Conn) {
	var arr = [3]string{}
	for i, v := range r.rooms {
		arr[i] = strconv.Itoa(len(v))
	}
	var res = map[string]interface{}{"mode": "allRoomsInfo", "allRoomsInfo": arr}
	for _, v := range r.rooms {
		for _, item := range v {
			var pipe = item.conn
			pipe.WriteJSON(res)
		}
	}
	// 把outsideRoom里的用户，广播所有的房间人数
	for _, v := range r.outsideRoom {
		var pipe = v.conn
		pipe.WriteJSON(res)
	}
	if user != nil {
		user.WriteJSON(res)
	}
}

// 人员离开时,把房间里的人删除
func (r *Rooms) resetRoomId(c *websocket.Conn) {
	for j, v := range r.rooms {
		var ptrV *[]User = &v
		for i, item := range *ptrV {
			if item.conn == c {
				v = append(v[:i], v[i+1:]...)
				r.rooms[j] = v
			}
		}
	}
	r.outsideRoom = append(r.outsideRoom, User{conn: c})
}

func (r *Rooms) add(c *websocket.Conn) {
	fmt.Println("进入房间")
	var index int //判断在那个房间,数组中的index
	ticker := time.NewTicker(10 * time.Second)
	var pingTime time.Time
	defer ticker.Stop()
	go func() {
		for {
			pingTime = <-ticker.C
			fmt.Println("10秒打印一次")
			var res = map[string]string{"mode": "ping"}
			c.WriteJSON(res)
		}
	}()
	for {
		var msg map[string]string
		_, message, err := c.ReadMessage()
		if err != nil {
			r.resetRoomId(c)
			fmt.Println("r退出时的房间=")
			r.boardRoomsNum(nil)
		}
		if len(message) == 0 {
			break
		}
		err = json.Unmarshal(message, &msg)
		if err != nil {
			fmt.Println("Unmarshal转换失败", message)
			break
		}
		if msg["mode"] == "door" {
			r.resetRoomId(c)
			var a = msg["door"]
			index, err = strconv.Atoi(a)
			if err != nil {
				fmt.Println("房间号准备失败")
			}
			var room = (r.rooms)
			if len(room[index]) >= 2 { //进入房间前房间人数大于两人，直接返回
				var res = map[string]string{"mode": "message", "message": "房间已满员！"}
				r.boardRoomsNum(c)
				c.WriteJSON(res)
				continue
			}
			var u User = User{conn: c}
			room[index] = append(room[index], u)
			r.boardRoomsNum(nil)
			// var res = map[string]string{"mode": "roomInfo", "num": strconv.Itoa(len(room[index]))}
			// fmt.Println("room[index]=", room[index])
			for _, v := range room[index] { //广播房间内所人,现在房间里的人数
				if v.conn != c { //告诉其中一方进入ready状态
					var res = map[string]string{"mode": "ready"}
					v.conn.WriteJSON(res)
				}
				// var co = v.conn
				// co.WriteJSON(res)
			}
		}
		if msg["mode"] == "loginOut" {
			r.resetRoomId(c)
			r.boardRoomsNum(c)
		}
		if msg["mode"] == "offer" {
			r.transformOffer(c, msg["offer"])
		}
		if msg["mode"] == "answer" {
			r.transformAnswer(c, msg["answer"])
		}
		if msg["mode"] == "ice" {
			r.transformIce(c, msg["ice"])
		}
		if msg["mode"] == "pong" {
			fmt.Printf("ticker.C_value:%v----ticker.C_type:%T\n", ticker.C, ticker.C)
			diff := time.Since(pingTime)
			fmt.Printf("pingTime与当前时间的差值: %v\n", diff)
			if diff > 2*time.Second {
				fmt.Println("差值大于2秒")
				c.Close()
			}
		}
	}
}

var upgrader = websocket.Upgrader{
	CheckOrigin: func(r *http.Request) bool {
		return true
	},
}

func Home(w http.ResponseWriter, r *http.Request) {
	conn, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Print("Error during connection upgradation:", err)
		return
	}
	defer conn.Close()
	allRooms.add(conn)
}
